Match the commands ls, cd, pwd
to their descriptions
ls
lists contents of
current
directory
cd
changes current
directory
cd
..
takes
you up
one
level
cd
alone
takes
you back
home
pwd
returns current
directory
Given a folder structure
diagram, a list of 'cd
(path)' commands and
target files, match the
paths to the target
files.
Use VSCode to create a
folder. Within the folder
create a .js file containing console.log('hello
new world');
and save it.
Use node to execute a
JavaScript file in the
terminal
Plain Old JS Object Lesson
Concepts
Label variables as either
Primitive vs.
Reference
primitives:
strings, booleans,
numbers, null and
undefined
primitives
are
immutable
refereces:
objects (including
arrays)
references
are
mutable
Identify when to use .
vs []
when accessing values of an
object
dot syntax object.key
easier
to
read
easier
to
write
cannot
use
variables
as
keys
keys
cannot
begin
with a
number
bracket notation object["key]
allows
variables
as
keys
strings
that
start
with
numbers
can be
use as
keys
Write an object literal
with a variable key using
interpolation
put it in
brackets to access
the value of the
variable, rather
than just make the
value that
string
1
let
a
="b";
2
let
obj
={a:"letter_a",[a]:"letter
b"}
Copied!
Use the obj[key] !==
undefined
pattern to check if a given
variable that contains a key
exists in an object
can also use (key in
object)
syntax
interchangeably
(returns a
boolean)
Utilize Object.keys and
Object.values in a
function
Object.keys(obj)
returns an array
of all the keys in obj
Object.values(obj)
returns an array
of the values in obj
Iterate through an object
using a for in
loop
1
letprintValues=function(obj){
2
for(let
key
in
obj){
3
let
value
=
obj[key];
4
console.log(value);
5
}
6
}
Copied!
Define a function that
utilizes ...rest
syntax to accept an
arbitrary number of
arguments
...rest
syntax will store
all additional
arguments in an
array
array will be
empty if there are
no additional
arguments
1
letmyFunction=function(str,...strs){
2
console.log("The
first
string
is
"+
str);
3
console.log("The
rest
of the
strings
are:");
4
strs.forEach(function(str){
5
console.log(str);
6
})
7
}
Copied!
Use ...spread
syntax for Object literals
and Array literals
1
let
arr1
=["a","b","c"];
2
let
longer
=[...arr1,"d","e"];//
["a",
"b",
"c",
"d",
"e"]
3
// without
spread syntax,
this would give
you a nested
array
4
let
withoutRest
=[arr1,"d","e"]//
[["a",
"b",
"c"],
"d",
"e"]
Copied!
Destructure an array to
reference specific
elements
```javascript
let array = [35,9];
let [firstEl, secondEl] =
array;
console.log(firstEl); //
=> 35
console.log(secondEl); //
=> 9
// can also destructure using ...
syntax let array = [35,9,14]; let
[head, ...tail] = array;
console.log(head); // => 35
console.log(tail); // => [9,
14]
1
-
Destructure an object to
reference specific
values
2
-if
you want to use variable
names that don't
match the keys,
you can use aliasing
3
-`let { oldkeyname:
newkeyname } =
object`
4
-
rule
of
thumbβonly destructure
values
from
objects that are two
levels deep
Given multiple plausible
reasons, identify why
functions are called
"First Class
Objects" in
JavaScript.
they can be
stored in
variables, passed
as arguments to
other functions,
and serve as
return value for a
function
supports same
basic operations
as other types
(strings, bools,
numbers)
higher-order
functions take
functions as
arguments or
return functions
as values
Given a code snippet
containing an anonymous
callback, a named callback,
and multiple console.logs, predict what will be
printed
what is this
referring
to?
Write a function that takes
in a value and two
callbacks. The function
should return the result of
the callback that is
greater.
1
letgreaterCB=function(val,
callback1,
callback2){
2
if(callback1(val)>callback2(val)){
3
returncallback1(val);
4
}
5
returncallback2(val);
6
}
7
β
8
β
9
β
10
letgreaterCB=function(val,
callback1,
callback2){
11
if(callback1(val)>callback2(val)){
12
returncallback1(val);
13
}
14
returncallback2(val);
15
}
Copied!
// shorter version let greaterCB =
function(val, callback1, callback2) {
return Math.max(callback1(val),
callback2(val)); } // even shorter,
cause why not let greaterCB = (val,
cb1, cb2) => Math.max(cb1(val),
cb2(val));
1
-
Write a
function,
myMap,
that takes
in
an array and a callback
as
arguments.
The
function
should mimic the behavior
of`Array#map`.
Write a function, myFilter,
that takes in an array and a
callback as arguments. The
function should mimic the
behavior of Array#filter.
1
letmyFilter=function(array,
callback){
2
let
filtered
=[];
3
for(let
i
=0;
i
<
array.length;
i
++){
4
if(callback(array[i])){
5
filtered.push(array[i],
i,
array);
6
}
7
}
8
}
Copied!
Write a function, myEvery,
that takes in an array and a
callback as arguments. The
function should mimic the
behavior of Array#every.
1
letmyEvery=function(array,
callback){
2
for(let
i
=0;
i
<
array.length;
i
++){
3
if(!callback(array[i],
i,
array)){
4
returnfalse
5
}
6
}
7
returntrue;
8
}
9
// with arrow
function
syntax
10
letmyEvery=(array,
callback)=>{
11
for(let
i
=0;
i
<
array.length;
i
++){
12
if(!callback(array[i])){
13
returnfalse
14
}
15
}
16
returntrue;
17
}
Copied!
Scope Lesson Concepts
Identify the difference
between const, let, and var
declarations
const
- cannot reassign
variable, scoped
to block
let
- can reassign
variable, scoped
to block
var
- outdated, may or
may not be
reassigned, scoped
to function. can
be not just
reassigned, but
also
redeclared!
a variable will
always evaluate to
the value it
contains
regardless of how
it was
declared
Explain the difference
between const, let, and var
declarations
var
is function
scopedβso if you
declare it
anywhere in a
function, the
declaration (but
not assignment) is
"hoisted"
so it
will
exist in
memory
as
"undefined"
which is
bad and
unpredictable
var
will also allow
you to redeclare a
variable, while let
or const
will raise a
syntax error. you
shouldn't be
able to do
that!
const
won't let you
reassign a
variable, but if
it points to a
mutable object,
you will still be
able to change the
value by mutating
the object
block-scoped
variables allow
new variables with
the same name in
new scopes
block-scoped
still performs
hoisting of all
variables within
the block, but it
doesn't
initialize to the
value of undefined
like var
does, so it throws
a specific
reference error if
you try to access
the value before
it has been
declared
if you do not use var
or let
or const
when initializing,
it will be
declared as
globalβTHIS IS
BAD
if you
assign a
value
without
a
declaration,
it
exists
in the
global
scope
(so then
it would
be
accessible
by all
outer
scopes,
so bad).
however,
there's
no
hoisting,
so it
doesn't
exist in
the
scope
until
after
the line
is
run
Predict the evaluation of
code that utilizes function
scope, block scope, lexical
scope, and scope
chaining
scope of a
program means the
set of variables
that are available
for use within the
program
global scope is
represented by the window
object in the
browser and the global
object in
Node.js
global
variables
are
available
everywhere,
and so
increase
the risk
of name
collisions
local scope is
the set of
variables
available for use
within the
function
when we
enter a
function,
we enter
a new
scope
includes
functions
arguments,
local
variables
declared
inside
function,
and any
variables
that
were
already
declared
when the
function
is
defined
(hmm
about
that
last
one)
for blocks
(denoted by curly
braces {}, as in
conditionals or for
loops), variables
can be block
scoped
inner scope does
not have access to
variables in the
outer scope
scope
chainingβif
a given
variable
is not
found in
immediate
scope,
javascript
will
search
all
accessible
outer
scopes
until
variable
is
found
so an
inner
scope
can
access
outer
scope
variables
but an
outer
scope
can
never
access
inner
scope
variables
Define an arrow
function
```javascript
let arrowFunction =
(param1, param2) =>
{
let sum = param1 +
param2;
return sum;
}
// with 1 param you can remove parens
around parameters let arrowFunction =
param => { param += 1; return
param; }
// if your return statement is one
line, you can use implied return let
arrowFunction = param => param +
1;
// you don't have to assign to
variable, can be anonymous // if you
never need to use it again param =>
param + 1;
```
Given an arrow function,
deduce the value of this
without executing the
code
arrow functions
are automatically
bound to the
context they were
declared in
unlike regular
function which use
the context they
are invoked in
(unless they have
been bound using Function#bind)
if you implement
an arrow function
as a method in an
object the context
it will be bound
to is NOT the
object itself, but
the global
context
so you can't
use an arrow
function to define
a method
directly
```javascript
let obj = {
name: "my
object",
unboundFunc:
function ()
{
return
this.name;
// this function
will be able to be
called on
different
objects
},
boundToGlobal: () => { return
this.name; // this function, no matter
how you call it, will be called // on
the global object, and it cannot be
rebound // this is because it was
defined using arrow syntax },
1
makeFuncBoundToObj:function(){
2
return()=>{
3
returnthis.name;
4
}
5
// this function will
return a function that
will be bound
6
// to the object where we
call the outer
method
7
// because the arrow
syntax is nested inside
one of this
8
// function's
methods, it cannot be
rebound
9
},
10
β
11
makeUnboundFunc:function(){
12
returnfunction(){
13
returnthis.name;
14
}
15
//this function will
return a function that
will still be
unbound
16
},
17
β
18
immediatelyInvokedFunc:function(){
19
returnthis.name;
20
}(),// this property will be
set to the return value of
this anonymous
function,
21
// which is invoked
during the object
definition;
22
// basically, it's a
way to check the context
inside of an object, at
this moment
23
β
24
innerObj:{
25
name:"inner
object",
26
innerArrowFunc:()=>{
27
returnthis.name;
28
}// the context inside a
nested object is not the
parent, it's
still
29
// the global object.
entering an object
definition doesn't
change the context
30
},
31
β
32
β
33
let
otherObj
={
name:"my other
object"}
34
// call unboundFunc on
obj, we get "my
object"
console.log("unboundFunc:
",
obj.unboundFunc()); //
=> "my
object" // assign
unboundFunc to a variable
and call it let newFunc =
obj.unboundFunc; // this
newFunc will default to
being called on global
object
console.log("newFunc:
",newFunc()); //
=> undefined // but you
could bind it directly to
a different object if you
wanted
console.log("newFunc:
",
newFunc.bind(otherObj)());
// "my other
object"
35
// meanwhile,
obj.boundToGlobal will
only ever be called on
global object
console.log("boundToGlobal:
",
obj.boundToGlobal());
//=> undefined let
newBoundFunc =
obj.boundToGlobal;
console.log("newBoundFunc:
", newBoundFunc());
// => undefined // even
if you try to directly
bind to another object, it
won't work!
console.log("newBoundFunc:
",
newBoundFunc.bind(otherObj)());
// => undefined
36
// let's make a new
function that will always
be bound to the context //
where we call our function
maker let boundFunc =
obj.makeFuncBoundToObj();//
note that we're
invoking, not just
assigning
console.log("boundFunc:
", boundFunc()); //
=> "my
object" // we
can't rebind this
function
console.log("boundFunc:
",
boundFunc.bind(otherObj)())
// =>"my
object"
37
// but if I call
makeFuncBoundToObj on
another context // the new
bound function is stuck
with that other context
let boundToOther =
obj.makeFuncBoundToObj.bind(otherObj)();
console.log("boundToOther:
", boundToOther());
// => "my other
object"
console.log("boundToOther:
",
boundToOther.bind(obj)())
// "my other
object"
38
// the return value of my
immediately invoked
function // shows that the
context inside of the
object is the // global
object, not the object
itself // context only
changes inside a function
that is called // on an
object
console.log("immediatelyInvokedFunc:
",
obj.immediatelyInvokedFunc);
// => undefined
39
// even though we're
inside a nested object,
the context is // still
the same as it was outside
the outer object // in
this case, the global
object
console.log("innerArrowFunc:
",
obj.innerObj.innerArrowFunc());
// => undefined
Copied!
}
1
-
Implement a closure and
explain how the closure
effects scope
2
-
a closure is
"the combination of
a function and the lexical
environment within which
that function was
declared"
3
-
alternatively,"when an inner
function uses or changes
variables in an outer
function"
4
-
closures have access to
any variables within their
own scope
+
scope
of
outer functions
+
global scope β the
setof
all these available
variables is
"lexical
environemnt"
5
-
closure keeps reference to
all variables
**even
if
the outer
function
has returned**
6
-
each
function
has a
private
mutable state that cannot
be accessed
externally
7
-
the inner
function
will maintain a reference
to the scope
in
which it was
declared.
so it has access to
variables that were
initialized
in
any outer scopeβeven
if
that scope
8
-if
a variable exists
in
the scope
of
what could have been
accessed by a
function(e.g.
global scope,
outer
function,
etc),
does that variable wind up
in
the closure even
if
it never got
accessed?
9
-if
you change the value
of
a
variable(e.g.
i++)
you will change the value
of
that variable
in
the scope that it was
declared
in
10
β
11
β
12
```javascript
13
functioncreateCounter(){
14
// this function starts a
counter at 0, then returns
a
15
// new function that can
access and change that
counter
16
//
17
// each new counter you
create will have a single
internal
18
// state, that can be
changed only by calling
the function.
19
// you can't access
that state from outside of
the function,
20
// even though the count
variable in question is
initialized
21
// by the outer function,
and it remains accessible
to the
22
// inner function after
the outer function
returns.
23
let
count
=0;
24
returnfunction(){
25
count ++;
26
return
count;
27
}
28
}
29
β
30
let
counter
=createCounter();
31
console.log(counter());//=> 1
32
console.log(counter());//=> 2
33
// so the closure here
comes into play
because
34
// an inner function is
accessing and
changing
35
// a variable from an
outer function
36
β
37
// the closure is the
combination of the
counter
38
// function and the all
the variables that
existed
39
// in the scope that it
was declared in.
because
40
// inner blocks/functions
have access to outer
41
// scopes, that includes
the scope of the
outer
42
// function.
43
β
44
// so counter variable is
a closure, in that
45
// it contains the inner
count value that was
46
// initialized by the
outer createCounter()
function
47
// count has been
captured or closed
over
48
β
49
// this state is private,
so if i run createCounter
again
50
// i get a totally
separate count that
doesn't
interact
51
// with the previous one
and each of the new
functions
52
// will have their own
internal state based on
the
53
// initial declaration in
the now-closed outer
function
54
β
55
let
counter2
=createCounter();
56
console.log(counter2());// => 1
57
β
58
// if i set a new
function equal to my
existing counter
59
// the internal state is
shared with the new
function
60
let
counter3
=
counter2;
61
console.log(counter3());
Copied!
Define a method that
references this
on an object literal
when we use this
in a method it
refers to the
object that the
method is invoked
on
it will
let you
access
other
pieces
of
information
from
within
that
object,
or even
other
methods
method
style
invocation
- object.method(args)
(e.g.
built in
examples
like Array#push, or String#toUpperCase)
context is set
every time we
invoke a
function
function style
invocation sets
the context to the
global object no
matter what
being inside an
object does not
make the context
that object! you
still have to use
method-style
invocation
Utilize the built in Function#bind
on a callback to maintain
the context of this
when we call bind
on a function, we
get an exotic
function backβso
the context will
always be the same
for that new
function
1
let cat = {
2
purr: function () {
3
console.log("meow");
4
},
5
purrMore: function () {
6
this.purr();
7
},
8
};
9
let sayMeow = cat.purrMore;
console.log(sayMeow()); //
TypeError: this.purr is not a
function
10
β
11
β
12
// we can use the built in
Function.bind to ensure our
context, our this, // is the cat
object let boundCat =
sayMeow.bind(cat);
13
boundCat(); // prints
"meow"
Copied!
``
1
-`bind`
can also work
with
arguments,
so you can have a version
of
a
functionwith
particular arguments and a
particular context.
the first arg will be the
context aka the
`this`
you want it to use.
the next arguments will be
the functions arguments
that you are binding
2
-if
you just want to bind it
to those arguments
in
particular,
you can use
`null`as
the first argument,
so the context won't
be bound,
just the arguments
3
-
Given a code snippet,
identify what
`this`
refers to
4
-
important to recognize the
difference between scope
and context
5
-
scope works like a
dictionary that has all
the variables that are
available within a given
block,
plus a pointer back the
next outer
scope(which itself has pointers
to
newscopes
until you reach the global
scope.
so you can think about a
whole given block's
scope
as
a kind
of
linked list
of
dictionaries)(also,this
is not to say that scope
is actually implemented
inthis
way,
that is just the schema
that i can use to
understand it)
6
-
context refers to the
value
of
the
`this`
keyword
7
-
the keyword
`this`
exists
in
every
function
and it evaluates to the
object that is currently
invoking that
function
8
-
so the context is fairly
straightforward when we
talk about methods being
called on specific
objects
9
-
you could,
however,
call an object's
method on something other
than that object,
and then
this
would refer to the context
where/how it was called,
e.g.
10
```javascript
11
let
dog
={
12
name:"Bowser",
13
changeName:function(){
14
this.name
="Layla";
15
},
16
};
17
β
18
// note this is **not
invoked** - we are
assigning the function
itself
CALLING SOMETHING IN THE
WRONG CONTEXT CAN MESS YOU
UP!
could throw an
error if it
expects this to
have some other
method or whatever
that doesn't
exist
you could also
overwrite values
or assign values
to exist in a
space where they
should not
exist
if you call a function as a
callback, it will set this
to be the outer function
itself, even if the function
you were calling is a method
that was called on a
particular object
1
let cat = {
2
purr: function ()
{
3
console.log("meow");
4
},
5
purrMore: function ()
{
6
this.purr();
7
},
8
};
9
global.setTimeout(cat.purrMore,
5000); // 5 seconds
later: TypeError:
this.purr is not a
function
Copied!
we can use strict mode with "use strict";
this will prevent you from accessing
the global object with this
in functions, so if you try to call this
in the global context and change a
value, you will get a type error, and
the things you try to access will be
undefined
let sayMeow = cat.purrMore;
console.log(sayMeow()); // TypeError:
this.purr is not a function
// we can use the built in
Function.bind to ensure our context,
our this, // is the cat object let boundCat =
sayMeow.bind(cat);
boundCat(); // prints
"meow"
1
- `bind` can also work with
arguments, so you can have a
version of a function with
particular arguments and a
particular context. the first
arg will be the context aka the
`this` you want it to use. the
next arguments will be the
functions arguments that you are
binding
2
- if you just want to bind it to
those arguments in particular,
you can use `null` as the first
argument, so the context
won't be bound, just the
arguments
3
- Given a code snippet,
identify what `this` refers
to
4
- important to recognize the
difference between scope and
context
5
- scope works like a dictionary
that has all the variables that
are available within a given
block, plus a pointer back the
next outer scope (which itself
has pointers to new scopes until
you reach the global scope. so
you can think about a whole
given block's scope as a
kind of linked list of
dictionaries) (also, this is not
to say that scope is actually
implemented in this way, that is
just the schema that i can use
to understand it)
6
- context refers to the value of
the `this` keyword
7
- the keyword `this` exists in
every function and it evaluates
to the object that is currently
invoking that function
8
- so the context is fairly
straightforward when we talk
about methods being called on
specific objects
9
- you could, however, call an
object's method on
something other than that
object, and then this would
refer to the context where/how
it was called, e.g.
10
```javascript
11
let dog = {
12
name: "Bowser",
13
changeName: function () {
14
this.name =
"Layla";
15
},
16
};
17
β
18
// note this is **not invoked**
- we are assigning the function
itself
CALLING SOMETHING IN THE
WRONG CONTEXT CAN MESS YOU
UP!
could throw an
error if it
expects this to
have some other
method or whatever
that doesn't
exist
you could also
overwrite values
or assign values
to exist in a
space where they
should not
exist
if you call a function as a
callback, it will set this
to be the outer function
itself, even if the function
you were calling is a method
that was called on a
particular object
```javascript
let cat = {
purr: function () {
console.log("meow");
},
purrMore: function ()
{
this.purr();
},
};
global.setTimeout(cat.purrMore,
5000); // 5 seconds later: TypeError:
this.purr is not a function
```
we can use strict mode with "use
strict";
this will prevent you from
accessing the global object
with this
in functions, so if you try
to call this
in the global context and
change a value, you will get
a type error, and the things
you try to access will be
undefined
POJOs
1. Label variables as either
Primitive vs. Reference
Javascript considers most data types
to be 'primitive', these
data types are immutable, and are
passed by value. The more complex data
types: Array and Object are mutable,
are considered 'reference'
data types, and are passed by
reference.
Boolean - Primitive
Null - Primitive
Undefined - Primitive
Number - Primitive
String - Primitive
Array - Reference
Object - Reference
Function - Reference
2. Identify when to use . vs [] when
accessing values of an object
1
let
obj
={"one":1,"two":2};
2
β
3
// Choose the square
brackets property accessor
when the property name is
determined at
4
// runtime, or if the
property name is not a
valid identifier
5
let
myKey
="one";
6
console.log(obj[myKey]);
7
β
8
// Choose the dot
property accessor when the
property name is known
ahead of time.
9
console.log(obj.two);
Copied!
3. Write an object literal with a
variable key using interpolation
1
let
keyName
="two";
2
β
3
// If the key is not
known, you can use an
alternative `[]` syntax
for
4
// object initialization
only
5
let
obj2
={[keyName]:2}
6
console.log(obj2);
Copied!
4. Use the obj[key] !== undefined
pattern to check if a given variable
that contains a key exists in an
object
1
functiondoesKeyExist(obj,
key){
2
// obj[key] !==
undefined
3
// or:
4
return
key
in
obj;
5
}
6
β
7
let
course
={
bootcamp:'Lambda',
course:'Bootcamp
Prep'}
1. Identify the difference between
const, let, and var declarations
2. Explain the difference between
const, let, and var declarations
1
var
a
="a";
Copied!
var
is the historical keyword
used for variable
declaration.
var
declares variables in
function scope, or global
scope if not inside a
function.
We consider var
to be deprecated
and it is never used in this
course.
1
let
b
="b";
Copied!
let
is the keyword we use most
often for variable
declaration.
let
declares variables in block
scope.
variables declared with let
are re-assignable.
1
const
c
="c";
Copied!
const
is a specialized form of let
that can only be used to initialize
a variable.
Except when it is declared,
you cannot assign to a const
variable.
const
scopes variables the same
way that let
does.
3. Predict the evaluation of code
that utilizes function scope, block
scope, lexical scope, and scope
chaining
Consider this run
function, inside which foo
and bar
have function scope. i
and baz
are scoped to the block
expression.
1
// function and block
scope in this
example
2
functionrun(){
3
var
foo
="Foo";
4
let
bar
="Bar";
5
β
6
console.log(foo,
bar);
7
β
8
{
9
console.log(foo);
10
let
baz
="Bazz";
11
console.log(baz);
12
}
13
β
14
console.log(baz);// ReferenceError
15
}
16
β
17
run();
Copied!
Notice that referencing baz
from outside it's block results
in JavaScript throwing a
ReferenceError.
Consider this run
function, inside of which foo
has function scope.
1
functionrun(){
2
console.log(foo);// undefined
3
var
foo
="Foo";
4
console.log(foo);// Foo
5
}
6
β
7
run();
Copied!
Consider this func1
function and it's nested
scopes.
1
// global scope
2
functionfunc1(arg1){
3
// func1 scope
4
β
5
returnfunctionfunc2(arg2){
6
// func2 scope
7
β
8
returnfunctionfunc3(arg3){
9
// func3 scope
10
β
11
console.log(arg1,
arg2,
arg3);
12
}
13
}
14
}
Copied!
6. Implement a closure and explain
how the closure effects scope
1
constadder=(arg1)=>{
2
return(arg2)=>{
3
return
arg1
+
arg2;
4
}
5
};
6
β
7
const
func2
=adder(2);
8
const
result
=func2(2);
9
console.log(result);// => 4;
Copied!
4. Define an arrow function
1
constreturnValue=(val)=>
val;
Copied!
This simple construct will create a
function that accepts val
as a parameter, and returns val
immediately. We do not need to type return val, because this is a single-line
function.
Identically, we could write
1
constreturnValue=(val)=>{
2
return
val;
3
};
Copied!
5. Given an arrow function, deduce
the value of this
without executing the code
If we use a function declaration
style function, the this
variable is set to the global
object (i.e. Object [global]
in Node.JS and Window
in your browser).
1
constadder=(arr)=>{
2
console.log(this);
3
arr.reduce((acc,
ele)=>
sum
+=
ele
);
4
};
5
adder([1,2,4,6]);
Copied!
In this example, we use a fat arrow
style function. Note that when we
declare a funciton like this this
becomes
7. Define a method that references
this on an object literal